package com.scalar.chiptrack.adaptor.gtc;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.FabSortLot;
import com.scalar.chiptrack.adaptor.InventoryLot;

import com.scalar.chiptrack.adaptor.dao.FabSortAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.InventoryLotDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * User: ChandraSekhar
 * Date: Nov 8, 2007
 * Time: 10:37:45 AM
 */
public class GTCDataParser extends JobHandler implements AdaptorConstants
{
    private static Logger m_parserLogger    = null;
    private String m_dataOutputDir          = null;

    private HashMap m_sortWipDataMap        = new HashMap();
	private HashMap m_waferBankDataMap		= new HashMap();

    public GTCDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir( VENDOR_NAME_GLOBAL_TEST_CORP, WIP_TYPE_SORT );

            if ( m_dataOutputDir != null )
            {
                AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );

                m_parserLogger = AdaptorUtils.getDataParserLogger( m_dataOutputDir,VENDOR_NAME_GLOBAL_TEST_CORP );
                FabSortAdaptorDAO.setLogger( m_parserLogger );   // All the DAOs and Parser should be logging into same file
                InventoryLotDAO.setLogger(m_parserLogger);
                AdaptorUtils.setLogger( m_parserLogger);
            }
        }
        catch ( ScalarException se )
        {
            log( "ERROR!! ERROR!! ERROR!! Exception while loading Global Test output/log directory details from database, Exception: " + se );
            throw se;
        }
    }
    /**
     *
     * @param args
     * @throws Exception
     */
    public static void main( String args[] ) throws Exception
    {
        new GTCDataParser().execute();
    }

    /**
     *
     */
    public void execute() throws Exception
    {
        AdaptorUtils.printHeader(VENDOR_NAME_GLOBAL_TEST_CORP, CONSTANT_PARSER);

        File doneDestDir = new File( m_dataOutputDir + "/done" );
        File dataoutDir  = new File( m_dataOutputDir );

        File[] fileList = dataoutDir.listFiles();

        if ( ( fileList == null ) || (fileList.length <= 3))
        {
            log("No file found in directory: " + dataoutDir);
            System.out.println("No file found in directory: " + dataoutDir );
            throw new ScalarException("No file found in directory: " + dataoutDir+ "----\n\n" );
        }

        ArrayList successFileList   = new ArrayList();
        boolean success             = false;

        try
        {
            for ( int i = 0; i < fileList.length; i++ )
            {
                if ( fileList[i].isDirectory() == true )
                {
                    continue;
                }
                
                if ( ( fileList[i].getName() != null ) && ( fileList[i].getName().trim().startsWith( GTCPOP3Adaptor.FILE_NAME_WIP_STATUS ) ) )
                {
                    ArrayList wipsheetDataList = parseWipSheetInfo( fileList[i].getAbsolutePath() );

                    if ( wipsheetDataList != null )
                    {
                        parseAllProcessWipList( wipsheetDataList );
                    }

                    successFileList.add( fileList[i] );
                }
            }
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! While parsing and storing File " + e );
            e.printStackTrace();
            throw e;
        }

		/*Updating the Wafer Store Lot Information*/
        try
        {
            // Save Wafer Store Information
            if (m_waferBankDataMap.isEmpty() == false)
            {
                log(" Updating Wafer Store Lot Information");
                InventoryLotDAO.saveInventoryLot(null, m_waferBankDataMap.values().iterator(), LOCATION_TYPE_WAFER_STORE, VENDOR_NAME_GLOBAL_TEST_CORP);
            }
            else
            {
                InventoryLotDAO.closeInventoryLot(null, LOCATION_TYPE_WAFER_STORE, VENDOR_NAME_GLOBAL_TEST_CORP);
            }
            success = true;
            m_waferBankDataMap.clear();
            m_waferBankDataMap = null;
        }
        catch (ScalarException se)
        {
            success = false;
            se.printStackTrace();
            log("ERROR!! ERROR!! ERROR!! Could not update Wafer Store Lot information into database: " + se);
            throw se;
        }
        // to save the Sort lot tables
        try
        {
            if ( m_sortWipDataMap.isEmpty() == false )
            {
                log( "Updating Sort Lot Information" );
                FabSortAdaptorDAO.saveSortLot( null, m_sortWipDataMap.values().iterator(), WIP_TYPE_SORT, VENDOR_NAME_GLOBAL_TEST_CORP );
                success = true;
            }

        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! Could not update Global Test Sort Data information into database: " + e );
            e.printStackTrace();
            throw e;
        }


        // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
        AdaptorDAO.sendAllNotifications( VENDOR_NAME_GLOBAL_TEST_CORP, true, true, true );

        AdaptorDAO.closeDropOutLots( VENDOR_NAME_GLOBAL_TEST_CORP );

        int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( GTCPOP3Adaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

        // Update Adaptor_Run_Info table
        try
        {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, GTCPOP3Adaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, GTCPOP3Adaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
        }

       // Move the successful files to 'done' directory
       if ( success )
       {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
       }
    }//end of execute method


    private  ArrayList parseWipSheetInfo( String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ArrayList wipSheetList  = new ArrayList();
        String line             = null;

        try
        {
            log( "\nFound " + fileName );
            log( "\nParsing the file for Global Test Wip Info..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for Global Test Wip Info..." );

            BufferedReader reader = new BufferedReader( new FileReader( fileName ) );
            reader.readLine();  // Read out First three Lines
            reader.readLine();
            reader.readLine();
            while ( ( line = reader.readLine() ) != null  && line.length() > 40 )
            {
                GTCWipInfo wipStatus = new GTCWipInfo();

                line = line.replaceAll( "\"", "" );

                String[] token = line.split( "," );
                for (int x = 0; x < token.length; x++)
                {
                    if (token[x] != null && token[x].trim().length() > 0)
                    {
                        switch (x)
                        {
                            case 0:
                                    wipStatus.setPartNumber( token[x].trim() );
                                    break;
                            case 1:
                                    wipStatus.setFablotNumber(token[x].trim());
                                    break;
                            case 2:
                                    wipStatus.setReceiveDate( token[x].trim());
                                    break;
                            case 3:
                                    wipStatus.setEbrNo( token[x].trim());
                                    break;
                            case 4:
                                    wipStatus.setStatus( token[x].trim() );
                                    break;
                            case 5:
                                    wipStatus.setStage( token[x].trim() );
                                    break;
                            case 6:
                                    wipStatus.setWaferBankQty( token[x].trim());
                                    break;
                            case 7:
                                    wipStatus.setSamlpeSortQty( token[x].trim() );
                                    break;
                            case 8:
                                    wipStatus.setFullSortQty( token[x].trim() );
                                    break;
                            case 9:
                                    wipStatus.setSortFgDieBankQty( token[x].trim() );
                                    break;
                            case 10:
                                    wipStatus.setExpectedDateOut( token[x].substring(0,10).trim() );
                                    break;
                            case 11:
                                    wipStatus.setLotNumber( token[x].trim() );
                                    break;
                            case 12:
                                    wipStatus.setWaferId( token[x].trim().replaceAll("/",";") +";" );
                                    break;
                            case 13:
                                    wipStatus.setHoldCode( token[x].trim() );
                                    break;
                         }
                    }
                }
                if ( wipStatus.getPartNumber() != null && wipStatus.getPartNumber().trim().length() > 0 )
                {
                    wipSheetList.add( wipStatus );
                }
            }
            try
            {
                if ( reader != null )
                {
                   reader.close();
                }
            }
            catch(IOException ignore)
            {

            }
        }
        catch ( Exception ex )
        {
            System.out.println("ERROR!!!ERROR!!! While Parsing the Global Test wip sheet");
            ex.printStackTrace();
            throw ex;
        }
        return wipSheetList;
    }



    /**
     *
     * @param wipdataList
     * @throws Exception
     */
    public void parseAllProcessWipList( ArrayList wipdataList ) throws Exception
    {
        if ( wipdataList == null || wipdataList.size() == 0 )
        {
            System.out.println("\n\n********* WIP Data was not found ******\n");
            return;
        }
        GTCWipInfo wipStatus  = null;
        String partNumber       = null;
        String lotNumber        = null;
        String fabLotNumber     = null;
        FabSortLot fabSortLot   = null;
		InventoryLot wsInventoryLot = null;

        try
        {
            Iterator iterator = wipdataList.iterator();

            while ( iterator.hasNext() )
            {
                wipStatus = ( GTCWipInfo ) iterator.next();

                partNumber = wipStatus.getPartNumber();
                lotNumber  = wipStatus.getLotNumber();
                fabLotNumber = wipStatus.getFablotNumber();

                if (lotNumber == null)
                {
                    lotNumber = fabLotNumber;
                }
                if ( partNumber != null && partNumber.trim().length() > 0 && lotNumber != null && lotNumber.trim().length() > 0 )
                {
					//WAFER STORE
					if ( wipStatus.getWaferBankQty() != null )
					{
						 wsInventoryLot = (InventoryLot) m_waferBankDataMap.get(partNumber + fabLotNumber);
                        if (wsInventoryLot == null)
                        {
                            wsInventoryLot = new InventoryLot(VENDOR_NAME_GLOBAL_TEST_CORP, LOCATION_TYPE_WAFER_STORE );
                            m_waferBankDataMap.put(partNumber + fabLotNumber, wsInventoryLot);
                        }

                        int quantity = 0;
                        if (wsInventoryLot.getWaferQtyIn() != null)
                        {
                            try
                            {
                                quantity = Integer.parseInt( wsInventoryLot.getWaferQtyIn() );
                            }
                            catch (NumberFormatException npe) {
                            }
                            try
                            {
                                quantity += Integer.parseInt( wipStatus.getWaferBankQty() );
                            }
                            catch (NumberFormatException npe) {
                            }
                        }
                        else
                        {
                            try
                            {
                                quantity = Integer.parseInt( wipStatus.getWaferBankQty() );
                            }
                            catch (NumberFormatException npe) {
                            }
                        }

                        if (quantity > 0)
                        {
                            wsInventoryLot.setLotNumber(fabLotNumber);
                            wsInventoryLot.setPartNumber(partNumber);
                            wsInventoryLot.setDateIn( wipStatus.getReceiveDate() );
                            wsInventoryLot.setWaferQtyIn(quantity + "");
                            wsInventoryLot.setStatus(LOT_STATUS_RUNNING);
                            wsInventoryLot.setFabLotNumber(fabLotNumber);
                            wsInventoryLot.setCategory(LOT_CATEGORY_TYPE_PROD);
                        }
                    
					}
					//SORT
                    if ( wipStatus.getFullSortQty() != null || wipStatus.getSortFgDieBankQty() != null )
                    {
                        fabSortLot = ( FabSortLot ) m_sortWipDataMap.get( partNumber + fabLotNumber);
                        if ( fabSortLot == null )
                        {
                            fabSortLot = new FabSortLot( VENDOR_NAME_GLOBAL_TEST_CORP, WIP_TYPE_SORT );
                            m_sortWipDataMap.put( partNumber + fabLotNumber , fabSortLot );
                        }

                        if( wipStatus.getFullSortQty() != null )
                        {
                            fabSortLot = ( FabSortLot ) m_sortWipDataMap.get( partNumber + fabLotNumber);

                            if( fabSortLot.getQtyIn() != null )
                            {
                                try
                                {
                                    fabSortLot.setQtyIn( ( Integer.parseInt( fabSortLot.getQtyIn() ) + Integer.parseInt( wipStatus.getFullSortQty() ) ) + "" );
                                }
                                catch(Exception e)
                                {
                                    fabSortLot.setQtyIn( wipStatus.getFullSortQty() );
                                }
                            }
                            else
                            {
                                fabSortLot.setQtyIn( wipStatus.getFullSortQty() );
                            }
                        }

                        if( wipStatus.getSortFgDieBankQty() != null  )
                        {
                            fabSortLot = ( FabSortLot ) m_sortWipDataMap.get( partNumber + fabLotNumber);

                            if( fabSortLot.getQtyIn() != null )
                            {
                                try
                                {
                                    fabSortLot.setQtyIn( ( Integer.parseInt( fabSortLot.getQtyIn() ) + Integer.parseInt( wipStatus.getSortFgDieBankQty() ) ) + "" );
                                }
                                catch(Exception e)
                                {
                                    fabSortLot.setQtyIn( wipStatus.getSortFgDieBankQty() );
                                }
                            }
                            else
                            {
                                fabSortLot.setQtyIn( wipStatus.getSortFgDieBankQty() );
                            }
                            
                            wipStatus.setStage("Sort FG");
                        }

                        if ( fabSortLot.getQtyIn() != null && fabSortLot.getQtyIn().equalsIgnoreCase("0") == false  )
                        {
                            fabSortLot.setLotId( fabLotNumber );
                            fabSortLot.setCustProduct( partNumber );
                            fabSortLot.setStage( wipStatus.getStage() );
                            fabSortLot.setFabLotNumber( fabLotNumber );
                            fabSortLot.setWaferID( wipStatus.getWaferId() );
                            fabSortLot.setLotCategory ( LOT_CATEGORY_TYPE_PROD );
                            fabSortLot.setDateIn(  wipStatus.getReceiveDate() ) ;
                            if ( wipStatus.getExpectedDateOut() != null )
                            {
                                fabSortLot.setForcastedDateOut( StringUtils.formatDate(wipStatus.getExpectedDateOut(), "yyyy-MM-dd", "MM/dd/yyyy" ) );
                            }
                            if ( wipStatus.getStatus() != null && "Hold".equalsIgnoreCase( wipStatus.getStatus() ) )
                            {
                                fabSortLot.setLotStatus( LOT_STATUS_HOLD );
                                fabSortLot.setHoldCode( wipStatus.getHoldCode() );
                            }
                            else
                            {
                                fabSortLot.setLotStatus( LOT_STATUS_RUNNING );
                            }
                        }
                    }
                }
            }
        }
        catch(Exception e)
        {
            System.out.println(" Error while parsing the Global Test wip status " + e);
            e.printStackTrace();
            throw e;
        }
    }
    /*private  ArrayList parseShipSheetInfo( String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Shipment Filename argument is null" );

        ArrayList shipSheetList = new ArrayList();
        String line             = null;

        try
        {
            log( "\nFound " + fileName );
            log( "\nParsing the file for EPSON Ship Info..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for EPSON Ship Info..." );

            BufferedReader reader = new BufferedReader( new FileReader( fileName ) );
            reader.readLine();  // Read out <Invoice Date> Line

            while ( ( line = reader.readLine() ) != null  && line.length() > 40 )
            {
                EpsonShipStatus shipStatus = new EpsonShipStatus();

                line = line.replaceAll( "\"", "" );

                String[] token = line.split( "," );
                for (int x = 0; x < token.length; x++)
                {
                    if (token[x] != null && token[x].trim().length() > 0)
                    {
                        switch (x)
                        {
                            case 0:
                                    shipStatus.setShipDate( token[x].trim() );
                                    break;
                            case 1:
                                    shipStatus.setInvoiceNo( token[x].trim());
                                    break;
                            case 2:
                                    shipStatus.setCustPo( token[x].trim());
                                    break;
                            case 3:
                                    shipStatus.setCustPartNo( token[x].trim());
                                    break;
                            case 4:
                                    shipStatus.setVendorPartNo( token[x].trim() );
                                    break;
                            case 5:
                                    shipStatus.setCustomerLot( token[x].trim() );
                                    break;
                            case 6:
                                    shipStatus.setShipWaferQty( token[x].trim());
                                    break;
                            case 7:
                                    shipStatus.setUm( token[x].trim() );
                                    break;
                            case 8:
                                    shipStatus.setWaferID( token[x].trim() );
                                    break;
                            case 9:
                                    shipStatus.setShipTo( token[x].trim() );
                                    break;
                         }
                    }
                }
                if ( shipStatus.getCustPartNo() != null && shipStatus.getCustPartNo().trim().length() > 0 )
                {
                    shipSheetList.add( shipStatus );
                }
            }
            try
            {
                if ( reader != null )
                {
                   reader.close();
                }
            }
            catch(IOException ignore)
            {

            }
        }
        catch ( Exception ex )
        {
            System.out.println("ERROR!!!ERROR!!! While Parsing the EPSON Ship sheet");
            ex.printStackTrace();
            throw ex;
        }
        return shipSheetList;
    }

    public void getShipStatusInfoList ( ArrayList shipdataList ) throws ScalarException
    {
       if ( shipdataList == null || shipdataList.size() == 0 )
       {
           System.out.println("\n\n********* Shipping data was found ******\n");
           return;
       }
       EpsonShipStatus shipStatusReport       = null;
       String partNumber                    = null;
       String lotNumber                     = null;
       ShippedLot shippedLot                = null;

       try
       {
           Iterator iterator = shipdataList.iterator();
           while ( iterator.hasNext() )
           {
               shipStatusReport = ( EpsonShipStatus ) iterator.next();

               if ( shipStatusReport != null )
               {
                   partNumber = shipStatusReport.getCustPartNo();
                   lotNumber  = shipStatusReport.getCustomerLot();

                   if ( lotNumber != null && partNumber != null )
                   {
                       shippedLot = ( ShippedLot ) shipDataMap.get( partNumber + lotNumber );
                       if ( shippedLot == null )
                       {
                           shippedLot = new ShippedLot( VENDOR_NAME_EPSON , WIP_TYPE_FAB );
                           shipDataMap.put( partNumber + lotNumber , shippedLot );
                       }
                       int quantity = 0;
                       if ( shippedLot.getShipQty() != null )
                       {
                           try
                           {
                               quantity = Integer.parseInt ( shippedLot.getShipQty() );
                           }
                           catch ( NumberFormatException ignore )
                           {
                           }
                           try
                           {
                               quantity += Integer.parseInt ( shipStatusReport.getShipWaferQty() );
                           }
                           catch ( NumberFormatException ignore )
                           {
                           }
                       }
                       else
                       {
                           try
                           {
                               quantity = Integer.parseInt ( shipStatusReport.getShipWaferQty() );
                           }
                           catch ( NumberFormatException ignore )
                           {
                           }
                       }

                       shippedLot.setPartNumber( partNumber);
                       shippedLot.setLotNumber( lotNumber );
                       shippedLot.setFabLotNumber( lotNumber );
                       shippedLot.setShipDate (  shipStatusReport.getShipDate() );
                       shippedLot.setShipQty ( quantity +"" );
                       shippedLot.setCustomerPO ( shipStatusReport.getCustPo() );
                       shippedLot.setWaferID( shipStatusReport.getWaferID() );
                       shippedLot.setInvoiceNumber( shipStatusReport.getInvoiceNo() );
                       shippedLot.setNextLocation( shipStatusReport.getShipTo() );
                   }
               }
           }
       }
       catch( Exception e)
       {
           log ("ERROR!!! ERROR!! While parsing the EPSON Data to Shipped Lot" + e);
           e.printStackTrace();
           throw new ScalarException ("ERROR!!! ERROR!! While parsing the EPSON Data to Shipped Lot" + e);
       }
    }*/
      
    private static void log( String message )
    {

        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            synchronized ( m_parserLogger )
            {
                m_parserLogger.logDebug( message + LINE_SEPARATOR );
            }
        }
        else
        {
            System.out.println( message );
        }
    }

}
